home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / System 7.0 Samples / AEObject-Edition1.0.2 Sample / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-18  |  17.9 KB  |  402 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------
  2. #
  3. #   Apple Developer Technical Support
  4. #
  5. #   AppleEvents & Edition Manager Sample Application
  6. #
  7. #   AEObject-Edition Sample
  8. #
  9. #   main.c  -   C Source
  10. #
  11. #   Copyright © 1990-1992 Apple Computer, Inc.
  12. #   All rights reserved.
  13. #
  14. #   Versions:   
  15. #                1.0.1                2/92       C.K. Haun <TR>
  16. #               1.0                11/91       C.K. Haun <TR>
  17. #               based on the EditionSample
  18. #   Components:
  19. #                           main.c
  20. #                           Menu.c
  21. #                           Files.c
  22. #                           Publish.c
  23. #                           Subscribe.c
  24. #                           TextSections.c
  25. #                           Windows.c
  26. #                           AppleEventCore.c
  27. #                           AEObject-Edition Sample.make                          
  28. #                           BuildHeaders.c
  29. #                            AEUtilities.c
  30. #                            AEObjects.c
  31. #                            Utilities.c
  32. #                            Initialize.c
  33. #                            globals.c
  34. #                            Print.c
  35. #                            prototypes.h
  36. #                            SampConstants.h
  37. #                            Structs.h
  38. #                            Macros.h
  39. #                           Sampdefines.h
  40. #
  41. #  
  42. #    This sample demonstrates the Apple Event Object model and
  43. #    the Edition Manager.
  44. #    It is an expanded version of the the earlier EditionSample,
  45. #    most of the changes (besides bug fixes) have been made in the 
  46. #    files AppleEventCore.c,AEUtilities.c and AEObjects.c.
  47. #    I decided to add the Object Model demonstration to the Edition Sample
  48. #    to use the objects (windows, shapes) that already existed 
  49. #    instead of developing a new sample.
  50. #    I beleive that the fuctional areas are discreet enough that 
  51. #    you can find what you are looking for without too much difficulty,
  52. #    the file names really do reflect the major contents of a
  53. #    specific source file.  
  54. #    
  55. #   This sample contains most of the Edition Manager calls that
  56. #   you'll need in your application.  It also contains one method
  57. #   for keeping track of the edition data for all your documents.
  58. #   It does NOT by any means demonstrate all the techniques 
  59. #   you need for a large application, nor the best data handling 
  60. #   methods for all cases.  
  61. #    
  62. #    This sample also implements some Apple Event Object model objects,
  63. #    specifically cWindow, cText,cWord,cGraphicLine,cRectangle and cOval.
  64. #
  65. #   Use this sample as a starting point, and adapt its' routines to 
  66. #   meet the specific needs of your project.  
  67. #   This sample will grow as more edition types are implemented,
  68. #   periodically check AppleLink for a later, expanded sample.
  69. #   This application is an example of the form of a Macintosh 
  70. #   application; it is NOT a template. It is NOT intended to be 
  71. #   used as a foundation for the next world-class, best-selling, 
  72. #   600K application. A stick figure drawing of the human body may 
  73. #   be a good example of the form for a painting, but that does not 
  74. #   mean it should be used as the basis for the next Mona Lisa.
  75. #    This sample's focus is the Edition Manager and AppleEvents, NOT
  76. #    drawing or text editing, so those areas are implemented in
  77. #    a very minimal fashion.  This is done to prevent obscuring the
  78. #    goal of this sample.  If you are interested in those (or other)
  79. #    areas, please look for a sample that focuses on them.
  80. #
  81. #
  82. ------------------------------------------------------------------------------*/
  83. #define __SAMPMAIN__
  84.  
  85. #pragma segment Main
  86.  
  87. #include "Sampdefines.h"
  88. #include <SegLoad.h>
  89.  
  90. extern void _DataInit();
  91. main()
  92. {
  93.     WindowPtr twindow;
  94.     Boolean x;
  95.     Boolean menuAction;
  96.     windowCHandle tempWCH;       
  97.     PScrapStuff theScrap;
  98.     short myScrapCount = -999;                               /* intialize to a silly value */
  99.     UnloadSeg((Ptr)_DataInit);                              /* throw the bums out */
  100.     StartStuff();                                           /* initialize managers and normal startup actions */
  101.     UnloadSeg((Ptr)StartStuff);
  102.     theScrap = InfoScrap();
  103.     FlushEvents(everyEvent, 0);
  104.     mousergn = NewRgn();
  105.     gStop = false;
  106.     while (!gStop){
  107.     
  108.     x = WaitNextEvent(everyEvent, &gERecord, gMySleep,mousergn);
  109.         theScrap = InfoScrap();
  110.         if (theScrap->scrapCount != myScrapCount) {
  111.             myScrapCount = theScrap->scrapCount;
  112.             UpdateScrap(true);
  113.         }
  114.         if (FrontWindow() != nil) {
  115.         /* if there is a text box, idle the cursor */
  116.             TEHandle tempTE;
  117.             windowCHandle tempWCH = (windowCHandle)GetWRefCon(FrontWindow());
  118.             tempTE = (*tempWCH)->boxHandle;
  119.             if (tempTE != nil)
  120.                 TEIdle(tempTE);                
  121.         }
  122.         switch (gERecord.what) {short fHit;
  123.             case nullEvent:
  124.             /* marching ants as necessary */
  125.                DoAnts(nil);
  126.                 break;
  127.             case updateEvt:
  128.                 DrawIt((WindowPtr)gERecord.message);                                   /* draw whatever window needs an update */
  129.                 break;
  130.             case mouseDown:
  131.                 /* first see where the hit was */
  132.                 fHit = FindWindow(gERecord.where, &twindow);
  133.                 switch (fHit) {Rect limitRect;
  134.                               long back;
  135.                               Str255 tempString;
  136.                     case inDesk:                            /* if they hit in desk, then the process manager */
  137.                         break;                              /* will switch us out, we don't need to do anything */
  138.                     case inMenuBar:
  139.                         /* If they clicked in the menu bar, we need to set up the Undo */
  140.                         /* text string for the current window, and the toggle of */
  141.                         /* Publisher or Subscriber options before we drop the */
  142.                         /* menu down. */
  143.                         /* Also change the Save string depending on the save state */
  144.                         /* Pull our aux data structure out of the current window */
  145.                         if (FrontWindow()) {
  146.                             tempWCH = (windowCHandle)GetWRefCon(FrontWindow());
  147.                             HLock((Handle)tempWCH);          /* lock it */
  148.                             AdjustMenus(tempWCH,FrontWindow());            /* in menu.c */
  149.                             HUnlock((Handle)tempWCH);
  150.                         } else {
  151.                             AdjustMenus(nil,nil);
  152.                         }
  153.                         /* Now we drop the menu down, and pass the results */
  154.                         /* to our menu handler (in Menu.c) */
  155.                         menuAction = DoSelected(MenuSelect(gERecord.where));
  156.                         break;
  157.                     case inSysWindow:
  158.                         /* pass to the system */
  159.                         SystemClick(&gERecord, twindow);
  160.                         break;
  161.                     case inContent:
  162.                         /* Our major workarea.  Depending on other factors, a */
  163.                         /* user could be drawing, moving a subscriber, selecting */
  164.                         /* a publisher or subscriber, selecting an area, or nothing. */
  165.                         /* First, if they did not click in the front window, we need */
  166.                         /* to bring the window they did click in to the front, and */
  167.                         /* pull the information we need (cursor mode, undo action, etc. ) */
  168.                         /* out of the aux record and update things */
  169.                         if (twindow != FrontWindow()) {
  170.                             ChangePlane(twindow);
  171.                         } else {
  172.                             if (FrontWindow()) {           /* don't do this unless we have a window open, silly */
  173.                                 windowCHandle clicker;
  174.                                 clicker = (windowCHandle)GetWRefCon(twindow);
  175.                                 /* jump to the content function stored for this window */
  176.                                 HLock((Handle)clicker);     /* lock it down so things don't get stupid */
  177.                                 (ProcPtr)((*clicker)->clickMe)(twindow);
  178.                                 HUnlock((Handle)clicker);       /* all done */
  179.                             }
  180.                         }
  181.                         break;
  182.                     case inDrag:
  183.                         DragWindow(twindow, gERecord.where, &qd.screenBits.bounds);
  184.                         break;
  185.                     case inGrow:
  186.                      SetPort(twindow);
  187.                         limitRect = qd.screenBits.bounds;
  188.                         limitRect.top = kMinHeight;
  189.                         GetWTitle(twindow, tempString);
  190.                         /* I'm not letting the user shrink the window so */
  191.                         /* small that the title is truncated */
  192.                         limitRect.left = StringWidth(tempString) + 120;
  193.                         back = GrowWindow(twindow,gERecord.where, &limitRect);
  194.                         if (back) {windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow);
  195.                             Rect sizeRect = ((WindowPtr)twindow)->portRect;                            
  196.                             sizeRect.top = sizeRect.bottom - 16;
  197.                             sizeRect.left = sizeRect.right - 16;
  198.                             EraseRect(&sizeRect);
  199.                             InvalRect(&sizeRect);                            
  200.                             SizeWindow(twindow, back & 0xffff, back >> 16, true);
  201.                             (ProcPtr)((*tempWCH)->sizeMe)(twindow);                            
  202.                         }
  203.                        
  204.                         InvalRect(&twindow->portRect);
  205.                         break;
  206.  
  207.                     case inGoAway:
  208.                         /* Track a click in the go away box.  If the user stays in it, */
  209.                         /* call the close proc for this window */
  210.                         if (TrackGoAway(twindow, gERecord.where))
  211.                             (ProcPtr)((*(windowCHandle)((WindowPeek)twindow)->refCon)->closeMe)(twindow);
  212.                         break;
  213.                     case inZoomIn:
  214.                     case inZoomOut:
  215.                     if (TrackBox(twindow, gERecord.where, fHit)) {windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow);
  216.                             SetPort(twindow);                            
  217.                             ZoomWindow(twindow, fHit, true);
  218.                             InvalRect(&twindow->portRect);                        
  219.                         (ProcPtr)((*tempWCH)->sizeMe)(twindow);
  220.                         }
  221.  
  222.                     break;                                        
  223.                 }
  224.             case mouseUp:
  225.                 /* don't care */
  226.                 break;
  227.                 /* same action for key or auto key */
  228.             case keyDown:
  229.             case autoKey:
  230.                 /* Do menu commands.  */
  231.                 /* Also check the window record for a TextEdit field, if there */
  232.                 /* is one pass the key to it */
  233.                 if (gERecord.modifiers & cmdKey) {
  234.                     if (FrontWindow()) {
  235.                         tempWCH = (windowCHandle)GetWRefCon(FrontWindow());
  236.                         HLock((Handle)tempWCH);              /* lock it */
  237.                         AdjustMenus(tempWCH,FrontWindow());                /* in menu.c */
  238.                         HUnlock((Handle)tempWCH);
  239.                     } else {
  240.                         AdjustMenus(nil,nil);
  241.                     }
  242.                     menuAction = DoSelected(MenuKey(gERecord.message & charCodeMask));
  243.                 } else {
  244.                     WindowPtr tempWP = FrontWindow();
  245.                     tempWCH = (windowCHandle)GetWRefCon(tempWP);
  246.                     if (((WindowPeek)tempWP)->windowKind == kDocumentWindow && ((*tempWCH)->boxHandle != nil)) {
  247.                     
  248.                         Boolean wasPC = false;
  249.                         tempWCH = (windowCHandle)GetWRefCon(tempWP);
  250.                         
  251.                         if ((*tempWCH)->textSections != nil) {
  252.                             /* this text box has sections, and the sections may need to be */
  253.                             /* adjusted by this keystroke.  First, see if it's a pure cursor move, */
  254.                             if (wasPC= PureCursor(gERecord.message & charCodeMask))
  255.                                 wasPC = SkipOverSubscriber(tempWCH, gERecord.message & charCodeMask);
  256.                             else
  257.                                 CheckTextSections(tempWCH, kKeyStroke);
  258.                         }
  259.                         if (!wasPC) {
  260.                             /* ExcludeSubscriber shortens the current selection if it impact on any */
  261.                             /* subscribers */
  262.                             ExcludeSubscriber(tempWCH);
  263.                             TEKey(gERecord.message & charCodeMask, (*tempWCH)->boxHandle);
  264.                             KillSelection(tempWCH);
  265.                         }
  266.                    
  267.                     }
  268.                     if(((WindowPeek)tempWP)->windowKind == kAEStatusWindow)AESKey(gERecord.message & charCodeMask,tempWCH);
  269.                 }
  270.                 break;
  271.             case keyUp:
  272.                 /* don't care */
  273.                 break;
  274.             case diskEvt:
  275.                 /* I don't do anything special for disk events, this just passes them */
  276.                 /* to a function that checks for an error on the mount */
  277.                 DoDiskEvents(gERecord.message);
  278.                 break;
  279.             case activateEvt:
  280.                 /* Draws on a window activate.  Other activate/deactivate stuff is */
  281.                 /* handled in either the ChangePlane function (for normal shuffling ) */
  282.                 /* or in the suspend/resume handler for layer swaps */
  283.                 if (gERecord.modifiers & activeFlag){
  284.                    ChangePlane((WindowPtr)gERecord.message);
  285.                     DrawIt((WindowPtr)gERecord.message);
  286.                     } else {
  287.                      windowCHandle tempWCH = (windowCHandle)GetWRefCon((WindowPtr)gERecord.message);
  288.                                 if ((*tempWCH)->boxHandle != nil)
  289.                                     TEDeactivate((*tempWCH)->boxHandle);
  290.                     }
  291.                 break;
  292.             case networkEvt:
  293.                 /* don't care */
  294.                 break;
  295.             case driverEvt:
  296.                 /* don't care */
  297.                 break;
  298.             case app4Evt:
  299.                 switch ((gERecord.message >> 24) & 0x0FF) {     /* high byte of message */
  300.                     case suspendResumeMessage:              /* suspend/resume is also an activate/deactivate */
  301.                         gInBackground = (gERecord.message & kResumeMask) == 0;
  302.                         if (gInBackground) {
  303.                             SpitClip();    /* export the clipboard please */
  304.                             /* If the clipboard is showing, hide it, since a clipboard */
  305.                             /* is not valid when you are in another layer */
  306.                             if(((WindowPeek)FindClipWindow())->visible == true)CloseClip(FindClipWindow());
  307.                             /* deactivate the current TextEdit record as necessary */
  308.                             if (FrontWindow() != nil) {
  309.                                 windowCHandle tempWCH = (windowCHandle)GetWRefCon(FrontWindow());
  310.                                 if ((*tempWCH)->boxHandle != nil)
  311.                                     TEDeactivate((*tempWCH)->boxHandle);
  312.                             /* set sleep value very high, since I'm doing no nul processing */        
  313.                             gMySleep = -1;
  314.                             }
  315.                             if (gShowSub || gShowPub) {
  316.                             /* I forget what this is here for.  Oh well */    
  317.                             }
  318.                         } else {
  319.                         gMySleep = 5;    /* wake up more */
  320.                             if (FrontWindow() != nil) {
  321.                                 windowCHandle tempWCH = (windowCHandle)GetWRefCon(FrontWindow());
  322.                                 if ((*tempWCH)->boxHandle != nil)
  323.                                     TEActivate((*tempWCH)->boxHandle);
  324.                             }
  325.                         }
  326.                         break;
  327.                     case mouseMovedMessage:
  328.                     AdjustCursor(gERecord.where, mousergn);
  329.                     break;
  330.                 }
  331.                 break;
  332.                 /* This dispatches high level events (AppleEvents, for example) */
  333.                 /* to our dispatch routine.  This is NEW in the event loop for */
  334.                 /* System 7 */
  335.             case kHighLevelEvent:
  336.                 DoHighLevel(gERecord);
  337.                 break;
  338.             default:
  339.                 break;
  340.  
  341.                 
  342.         }        
  343.     }
  344.     /* save current prferences on exit */
  345.     SavePrefs();    
  346. }
  347.  
  348.  
  349. /* DrawIt calls the drawing routine for the window that requires a refresh,
  350. * either for a update or activate 
  351. */
  352. void DrawIt(WindowPtr theWindow)
  353. {
  354.     WindowPtr  tempwind;
  355.     windowCHandle tempWCH;
  356.     GetPort(&tempwind);                                     /* save the current port */                                                                                         
  357.     BeginUpdate(theWindow);                                   /* tell window manager to do it's thing */
  358.     SetPort(theWindow);
  359.     EraseRgn(theWindow->visRgn);                              /* erase whatever needs updating, remember that
  360.                                                             BeginUpdate copies the update region into the visRgn */
  361.     /* pull our control structure out of the refCon */
  362.     tempWCH = (windowCHandle)GetWRefCon(theWindow);
  363.     HLock((Handle)tempWCH);                                 /* lock it down so things don't get stupid */
  364.     /* jump to the drawing function stored for this window */
  365.     (ProcPtr)((*tempWCH)->drawMe)(tempWCH, theWindow);
  366.     HUnlock((Handle)tempWCH);                               /* all done */
  367.     EndUpdate(theWindow);                                     /* all done */
  368.     SetPort(tempwind);                                      /* reset the port to the entry port */
  369. }
  370.  
  371. /* DrawIt */
  372.  
  373.  
  374.  
  375. void DeBorderSelection(void)
  376. {
  377.     if (gShowPub) {
  378.         gShowPub = false;
  379.         gShowingSecHandle = nil;
  380.         InsetRect(&gShowPubRect, kNegFour, kNegFour);
  381.         InvalRect(&gShowPubRect);
  382.         InsetRect(&gShowPubRect, kFour, kFour);
  383.     } else {
  384.         if (gShowSub) {
  385.             gShowSub = false;
  386.             gShowingSecHandle = nil;
  387.             InsetRect(&gShowSubRect, kNegFour, kNegFour);
  388.             InvalRect(&gShowSubRect);
  389.             InsetRect(&gShowSubRect, kFour, kFour);
  390.         }
  391.     }
  392. }
  393.  
  394. /* Just in case I need a nothing proc, here's one.  In Main so I'm not dragging in other segments */
  395. void NilProc(void)
  396. {
  397. }
  398.  
  399.  
  400.  
  401. #undef __SAMPMAIN__
  402.